package com.example.cardgame.model

class CardMatchingGame(
    val count: Int,
    private var matchCount: Int = 2 // 默认2张匹配
) {
    var score = 0
        private set

    val cards: MutableList<Card> = mutableListOf()

    // 记录用户选择的卡片索引（用于匹配逻辑）
    private val selectedIndices = mutableListOf<Int>()

    // 分数规则（基于匹配结果动态调整）
    private val MISMATCH_PENALTY = 2 // 不匹配惩罚
    private val COST_TO_CHOOSE = 1 // 选择成本

    init {
        require(matchCount >= 2) { "匹配张数至少为2" }
        reset() // 初始化时直接调用reset生成卡片
    }

    // 动态修改匹配张数（修改后重置游戏确保卡片组合理）
    fun setMatchCount(newCount: Int) {
        require(newCount >= 2) { "匹配张数至少为2" }
        matchCount = newCount
        reset()
    }

    // 重置游戏：重新生成卡片、清空分数和选择记录
    fun reset() {
        score = 0
        selectedIndices.clear()
        cards.clear()

        // 确保卡片总数是matchCount的倍数（保证能组成完整匹配组）
        val actualCount = if (count % matchCount == 0) count else count + (matchCount - count % matchCount)

        // 使用Deck抽取随机卡片（Deck已包含所有花色和点数的卡片）
        val deck = Deck()
        // 抽取actualCount张卡片（若Deck卡片不足则循环抽取，避免空值）
        repeat(actualCount) {
            var card: Card? = null
            // 若Deck中无卡片，重新创建Deck（防止抽完）
            while (card == null) {
                if (deck.drawRandomCard() == null) {
                    // Deck已空，重新初始化Deck
                    deck.apply {
                        cards.clear()
                        for (suit in Card.validSuits) {
                            for (rank in Card.rankStrings) {
                                cards.add(Card(suit, rank))
                            }
                        }
                    }
                } else {
                    card = deck.drawRandomCard()
                }
            }
            cards.add(card!!)
        }
    }

    // 通过索引获取卡片
    fun cardAtIndex(index: Int): Card {
        if (index < 0 || index >= cards.size) {
            throw IndexOutOfBoundsException("卡片索引越界：$index（总卡片数：${cards.size}）")
        }
        return cards[index]
    }

    /**
     * 选择卡片逻辑（兼容Fragment中的双参数调用）
     * @param index 选中卡片的索引
     * @param currentMatchCount 当前游戏的匹配张数（2或3）
     */
    fun chooseCardAtIndex(index: Int, currentMatchCount: Int) {
        // 更新当前匹配张数（确保与Fragment设置一致）
        this.matchCount = currentMatchCount
        val card = cardAtIndex(index)

        // 已匹配的卡片不可再操作
        if (card.isMatched) return

        // 取消已选中卡片的选择状态
        if (card.isChosen) {
            card.isChosen = false
            selectedIndices.remove(index)
            score += COST_TO_CHOOSE // 退还选择成本
            return
        }

        // 选中新卡片：记录索引、标记状态、扣除选择成本
        selectedIndices.add(index)
        card.isChosen = true
        score -= COST_TO_CHOOSE

        // 当选中数量达到当前匹配张数时，验证匹配
        if (selectedIndices.size == matchCount) {
            // 获取所有选中的卡片（当前卡片+其他选中卡片）
            val baseCard = cards[selectedIndices[0]]
            val otherSelectedCards = selectedIndices.subList(1, selectedIndices.size).map { cards[it] }

            // 调用Card类的match方法判断是否匹配（返回匹配分数）
            val matchScore = baseCard.match(otherSelectedCards)

            if (matchScore > 0) {
                // 匹配成功：标记所有选中卡片为已匹配，清空选择记录，加分
                selectedIndices.forEach { cards[it].isMatched = true }
                selectedIndices.clear()
                score += matchScore // 直接使用Card.match返回的分数作为奖励
            } else {
                // 匹配失败：仅保留最后一张选中状态，扣分
                score -= MISMATCH_PENALTY

                // 取消除最后一张外的所有选中卡片的状态
                for (i in 0 until selectedIndices.size - 1) {
                    cards[selectedIndices[i]].isChosen = false
                }

                // 仅保留最后一张卡片的选中记录
                val lastIndex = selectedIndices.last()
                selectedIndices.clear()
                selectedIndices.add(lastIndex)
            }
        }
    }
}